package com.hpq.user.service.impl;

import com.hpq.common.event.UserBlackEvent;
import com.hpq.user.dao.BlackDAO;
import com.hpq.user.dao.UserDAO;
import com.hpq.user.domain.enums.BlackTypeEnum;
import com.hpq.user.domain.enums.RoleEnum;
import com.hpq.user.domain.model.Black;
import com.hpq.user.domain.model.IpInfo;
import com.hpq.user.domain.model.User;
import com.hpq.user.domain.vo.request.user.BlackReq;
import com.hpq.user.service.RoleService;
import com.hpq.user.service.cache.UserCache;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;
import java.util.Set;

/**
 *  角色服务实现类
 */
@Service
public class RoleServiceImpl implements RoleService {
    @Autowired
    private UserCache userCache;
    @Autowired
    private BlackDAO blackDao;
    @Autowired
    private UserDAO userDao;
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;
    /**
     *  判断用户是否有权限
     * @param uid
     * @param roleEnum
     * @return
     */
    @Override
    public boolean hasPower(Long uid, RoleEnum roleEnum) {
        Set<Long> roleIds = userCache.getRoleByUid(uid);
        return isAdmin(roleIds) || roleIds.contains(roleEnum.getId());
    }
    /**
     * 判断是否是管理员
     * @param roleIds
     * @return
     */
    public boolean isAdmin(Set<Long> roleIds){
        return roleIds.contains(RoleEnum.ADMIN.getId());
    }
    /**
     *  拉黑用户
     * @param req
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void black(BlackReq req) {
        Long uid = req.getUid();
        Black user = new Black();
        user.setType(BlackTypeEnum.UID.getType());
        user.setTarget(uid.toString());
        blackDao.save(user);
        User userById = userDao.getById(uid);
        blackIp(Optional.ofNullable(userById.getIpInfo()).map(IpInfo::getCreateIp).orElse(null));
        blackIp(Optional.ofNullable(userById.getIpInfo()).map(IpInfo::getUpdateIp).orElse(null));
        applicationEventPublisher.publishEvent(new UserBlackEvent(this,userById));
    }

    /**
     * 拉黑用户的createIp和updateIp
     * @param ip
     */
    private void blackIp(String ip) {
        if(StringUtils.isBlank(ip)){
            return;
        }
        Black user = new Black();
        user.setType(BlackTypeEnum.IP.getType());
        user.setTarget(ip);
        blackDao.save(user);
    }

}
